#include "RbTableHeaderView.h"

#include <QPainter>
#include <QBrush>
#include <QStandardItem>
#include <QMouseEvent>
#include <qdrawutil.h>

RbTableHeaderItem::RbTableHeaderItem(RbTableHeaderItem *parent)
    : row_prop(0)
      , column_prop(0)
      , parent_item(parent) {
}

RbTableHeaderItem::RbTableHeaderItem(int arow, int acolumn, RbTableHeaderItem *parent)
    : row_prop(arow)
      , column_prop(acolumn)
      , parent_item(parent) {
}

RbTableHeaderItem::~RbTableHeaderItem() {
}

RbTableHeaderItem *RbTableHeaderItem::insertChild(int row, int col) {
    RbTableHeaderItem *newChild = new RbTableHeaderItem(row, col, this);
    child_items.insert(QPair<int, int>(row, col), newChild);
    return newChild;
}

const RbTableHeaderItem *RbTableHeaderItem::child(int row, int col) const {
    QHash<QPair<int, int>, RbTableHeaderItem *>::const_iterator itr = child_items.find(QPair<int, int>(row, col));
    if (itr != child_items.end())
        return itr.value();
    return 0;
}

RbTableHeaderItem *RbTableHeaderItem::child(int row, int col) {
    QHash<QPair<int, int>, RbTableHeaderItem *>::iterator itr = child_items.find(QPair<int, int>(row, col));
    if (itr != child_items.end())
        return itr.value();
    return 0;
}

void RbTableHeaderItem::setText(const QString &text) {
    role_datas.insert(Qt::DisplayRole, text);
}

QVariant RbTableHeaderItem::data(int role) const {
    QHash<int, QVariant>::const_iterator itr = role_datas.find(role);
    if (itr != role_datas.end())
        return itr.value();
    return QVariant();
}

void RbTableHeaderItem::setData(const QVariant &data, int role) {
    role_datas.insert(role, data);
}

void RbTableHeaderItem::clear() {
    QList<RbTableHeaderItem *> items = child_items.values();
    foreach(RbTableHeaderItem * item, child_items) {
        if (item) delete item;
    }
    child_items.clear();
}

RbTableHeaderModel::RbTableHeaderModel(int rows, int cols, QObject *parent)
    : QAbstractTableModel(parent)
      , row_count_prop(rows)
      , column_count_prop(cols)
      , root_item(new RbTableHeaderItem()) {
}

RbTableHeaderModel::~RbTableHeaderModel() {
    root_item->clear();
    delete root_item;
}

/**
 *平面结构,一般不需要parent,tree需要parent'
 * @param row
 * @param column
 * @param parent
 * @return
 */
// QModelIndex(0,0, root_item) -> "A"
// │
// ├── QModelIndex(0,0, A) -> "A1"
// └── QModelIndex(0,1, A) -> "A2"
//
// QModelIndex(0,1, root_item) -> "B"
// │
// ├── QModelIndex(0,0, B) -> "B1"
// └── QModelIndex(0,1, B) -> "B2"
// “在 parent 节点下，返回第 row 行、第 column 列的 子项索引。”
QModelIndex RbTableHeaderModel::index(int row, int column, const QModelIndex &parent) const {
    if (!hasIndex(row, column, parent))
        return QModelIndex();

    //这就是在确定“我要从哪个父节点里去找子项”。如果 parent 是空的 → 我从根节点找（顶层表头）否则 → 我从某个子节点的孩子中找。
    RbTableHeaderItem *parentItem;
    if (!parent.isValid())
        parentItem = root_item; // parent item is always the root_item on table model
    else
        parentItem = static_cast<RbTableHeaderItem *>(parent.internalPointer()); // no effect

    //“从父节点的子项表中找到 (row, column) 的子节点，如果还没有，就新建一个。”
    RbTableHeaderItem *childItem = parentItem->child(row, column);
    if (!childItem)
        childItem = parentItem->insertChild(row, column);
    return createIndex(row, column, childItem);
}

QVariant RbTableHeaderModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid())
        return QVariant();

    if (index.row() >= row_count_prop || index.row() < 0 || index.column() >= column_count_prop || index.column() < 0)
        return QVariant();

    // 根据index获取item
    RbTableHeaderItem *item = static_cast<RbTableHeaderItem *>(index.internalPointer());

    //item的数据结构,存储qhash<int,QVariant>,角色:数据
    return item->data(role);
}

bool RbTableHeaderModel::setData(const QModelIndex &index, const QVariant &value, int role) {
    if (index.isValid()) {
        RbTableHeaderItem *item = static_cast<RbTableHeaderItem *>(index.internalPointer());
        if (role == COLUMN_SPAN_ROLE) {
            int col = index.column();
            int span = value.toInt();
            if (span > 0) // span size should be more than 1, else nothing to do
            {
                if (col + span - 1 >= column_count_prop) // span size should be less than whole columns,
                    span = column_count_prop - col;
                item->setData(span, COLUMN_SPAN_ROLE);
            }
        } else if (role == ROW_SPAN_ROLE) {
            int row = index.row();
            int span = value.toInt();
            if (span > 0) // span size should be more than 1, else nothing to do
            {
                if (row + span - 1 >= row_count_prop)
                    span = row_count_prop - row;
                item->setData(span, ROW_SPAN_ROLE);
            }
        } else
            item->setData(value, role);

        return true;
    }
    return false;
}

//索引无效的话，默认返回Qt::ItemIsEnabled；否则可编辑
Qt::ItemFlags RbTableHeaderModel::flags(const QModelIndex &index) const {
    if (!index.isValid())
        return Qt::ItemIsEnabled;
    return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}

void RbTableHeaderModel::rebuildHeaderStructure()
{
    if (!root_item)
        root_item = new RbTableHeaderItem();

    root_item->clear();
    for (int r = 0; r < row_count_prop; ++r) {
        for (int c = 0; c < column_count_prop; ++c) {
            auto item = new RbTableHeaderItem();
            item->setText(QString("Header %1,%2").arg(r).arg(c));
            // root_item->insertChild(item);
        }
    }
}

void RbTableHeaderModel::setHeaderRowCount(int rows)
{
    if (rows == row_count_prop)
        return;

    beginResetModel();
    row_count_prop = rows;
    rebuildHeaderStructure();
    endResetModel();
}

void RbTableHeaderModel::setHeaderColumnCount(int cols)
{
    if (cols == column_count_prop)
        return;

    beginResetModel();
    column_count_prop = cols;
    rebuildHeaderStructure();
    endResetModel();
}

RbTableHeaderView::RbTableHeaderView(Qt::Orientation orientation, int rows, int columns, QWidget *parent)
    : QHeaderView(orientation, parent),
    m_rows(rows), m_columns(columns){
    QSize baseSectionSize;
    if (orientation == Qt::Horizontal) {
        baseSectionSize.setWidth(defaultSectionSize());
        baseSectionSize.setHeight(20);
    } else {
        baseSectionSize.setWidth(50);
        baseSectionSize.setHeight(defaultSectionSize());
    }

    // create header model
     headerModel = new RbTableHeaderModel(rows, columns);

    // set default size of item
    for (int row = 0; row < m_rows; ++row)
        for (int col = 0; col < m_columns; ++col)
            headerModel->setData(headerModel->index(row, col), baseSectionSize, Qt::SizeHintRole);

    setModel(headerModel);

    connect(this, SIGNAL(sectionResized(int, int, int)), this, SLOT(onSectionResized(int, int, int)));
}

RbTableHeaderView::RbTableHeaderView(Qt::Orientation orientation, QWidget *parent)
    : QHeaderView(orientation, parent)
{
    connect(this, SIGNAL(sectionResized(int, int, int)), this, SLOT(onSectionResized(int, int, int)));

}

//todo
void RbTableHeaderView::setRowAndColumn(int rows, int columns) {
    m_rows = rows;
    m_columns = columns;

    QSize baseSectionSize;
    if (orientation() == Qt::Horizontal) {
        baseSectionSize.setWidth(defaultSectionSize());
        baseSectionSize.setHeight(30);
    } else {
        baseSectionSize.setWidth(50);
        baseSectionSize.setHeight(defaultSectionSize());
    }
    if (headerModel) {

    }

    //todo 此处有内存释放;
    // if (headerModel) {
    //     this->setModel(nullptr);
    //     headerModel->setParent(nullptr); // 防止旧父子冲突
    //     headerModel->deleteLater();      // ✅ 同样安全
    // }

    headerModel = new RbTableHeaderModel(m_rows, m_columns);

    for (int row = 0; row < m_rows; ++row)
        for (int col = 0; col < m_columns; ++col)
            headerModel->setData(headerModel->index(row, col), baseSectionSize, Qt::SizeHintRole);

    setModel(headerModel);
}

RbTableHeaderView::~RbTableHeaderView() {
}

//�����и�
void RbTableHeaderView::setRowHeight(int row, int rowHeight) {
    RbTableHeaderModel *md = qobject_cast<RbTableHeaderModel *>(model());
    const int cols = md->columnCount();
    for (int col = 0; col < cols; ++col) {
        QSize sz = md->index(row, col).data(Qt::SizeHintRole).toSize();
        sz.setHeight(rowHeight);
        md->setData(md->index(row, col), sz, Qt::SizeHintRole);
    }
    if (orientation() == Qt::Vertical)
        resizeSection(row, rowHeight);
}

void RbTableHeaderView::setColumnWidth(int col, int colWidth) {
    RbTableHeaderModel *md = qobject_cast<RbTableHeaderModel *>(model());
    const int rows = md->rowCount();
    for (int row = 0; row < rows; ++row) {
        QSize sz = md->index(row, col).data(Qt::SizeHintRole).toSize();
        sz.setWidth(colWidth);
        md->setData(md->index(row, col), sz, Qt::SizeHintRole);
    }
    if (orientation() == Qt::Horizontal)
        resizeSection(col, colWidth);
}

void RbTableHeaderView::setRowNumber(int rows) {
    headerModel->setHeaderRowCount(rows);
}

void RbTableHeaderView::setColumnNumber(int columns) {
    headerModel->setHeaderColumnCount(columns);
}


//�洢��ָ��index ��硢���䵥Ԫ��
void RbTableHeaderView::setSpan(int row, int column, int rowSpanCount, int columnSpanCount) {
    RbTableHeaderModel *md = qobject_cast<RbTableHeaderModel *>(model());
    QModelIndex idx = md->index(row, column);
    if (rowSpanCount > 0)
        md->setData(idx, rowSpanCount, ROW_SPAN_ROLE);
    if (columnSpanCount)
        md->setData(idx, columnSpanCount, COLUMN_SPAN_ROLE);
}

void RbTableHeaderView::setCellBackgroundColor(const QModelIndex &index, const QColor &color) {
    RbTableHeaderModel *md = qobject_cast<RbTableHeaderModel *>(model());
    md->setData(index, color, Qt::BackgroundRole);
}

void RbTableHeaderView::setCellForegroundColor(const QModelIndex &index, const QColor &color) {
    RbTableHeaderModel *md = qobject_cast<RbTableHeaderModel *>(model());
    md->setData(index, color, Qt::ForegroundRole);
}


// void RbTableHeaderView::mousePressEvent(QMouseEvent *event) {
//     QHeaderView::mousePressEvent(event);
//     QPoint pos = event->pos();
//     QModelIndex index = indexAt(pos);
//     const int OTN = orientation();
//     if (index.isValid()) {
//         int beginSection = -1;
//         int endSection = -1;
//         int numbers = 0;
//         numbers = getSectionRange(index, &beginSection, &endSection);
//         if (numbers > 0) {
//             emit sectionPressed(beginSection, endSection);
//             return;
//         } else {
//             const RbTableHeaderModel *tblModel = qobject_cast<RbTableHeaderModel *>(this->model());
//             const int LEVEL_CNT = (OTN == Qt::Horizontal) ? tblModel->rowCount() : tblModel->columnCount();
//             int logicalIdx = (OTN == Qt::Horizontal) ? index.column() : index.row();
//             int curLevel = (OTN == Qt::Horizontal) ? index.row() : index.column();
//             for (int i = 0; i < LEVEL_CNT; ++i) {
//                 QModelIndex cellIndex = (OTN == Qt::Horizontal)
//                                             ? tblModel->index(i, logicalIdx)
//                                             : tblModel->index(logicalIdx, i);
//                 numbers = getSectionRange(cellIndex, &beginSection, &endSection);
//                 if (numbers > 0) {
//                     if (beginSection <= logicalIdx && logicalIdx <= endSection) {
//                         int beginLevel = (OTN == Qt::Horizontal) ? cellIndex.row() : cellIndex.column();
//                         QVariant levelSpanCnt = cellIndex.data(
//                             (OTN == Qt::Horizontal) ? ROW_SPAN_ROLE : COLUMN_SPAN_ROLE);
//                         if (!levelSpanCnt.isValid())
//                             continue;
//                         int endLevel = beginLevel + levelSpanCnt.toInt() - 1;
//                         if (beginLevel <= curLevel && curLevel <= endLevel) {
//                             emit sectionPressed(beginSection, endSection);
//                             break;
//                         }
//                     }
//                 }
//             }
//         }
//     }
// }

// QModelIndex RbTableHeaderView::indexAt(const QPoint &pos) {
//     const RbTableHeaderModel *tblModel = qobject_cast<RbTableHeaderModel *>(this->model());
//     const int OTN = orientation();
//     const int ROWS = tblModel->rowCount();
//     const int COLS = tblModel->columnCount();
//     int logicalIdx = logicalIndexAt(pos);
//
//     if (OTN == Qt::Horizontal) {
//         int dY = 0;
//         for (int row = 0; row < ROWS; ++row) {
//             QModelIndex cellIndex = tblModel->index(row, logicalIdx);
//             dY += cellIndex.data(Qt::SizeHintRole).toSize().height();
//             if (pos.y() <= dY) return cellIndex;
//         }
//     } else {
//         int dX = 0;
//         for (int col = 0; col < COLS; ++col) {
//             QModelIndex cellIndex = tblModel->index(logicalIdx, col);
//             dX += cellIndex.data(Qt::SizeHintRole).toSize().width();
//             if (pos.x() <= dX) return cellIndex;
//         }
//     }
//
//     return QModelIndex();
// }

void RbTableHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIdx) const {
    const RbTableHeaderModel *tblModel = qobject_cast<RbTableHeaderModel *>(this->model());
    const int OTN = orientation();
    const int LEVEL_CNT = (OTN == Qt::Horizontal) ? tblModel->rowCount() : tblModel->columnCount();
    for (int i = 0; i < LEVEL_CNT; ++i) {
        QModelIndex cellIndex = (OTN == Qt::Horizontal)
                                    ? tblModel->index(i, logicalIdx)
                                    : tblModel->index(logicalIdx, i);
        QSize cellSize = cellIndex.data(Qt::SizeHintRole).toSize();
        QRect sectionRect(rect);

        // set position of the cell

        if (OTN == Qt::Horizontal)
        //     // 从第 0 层到第 i-1 层的所有高度之和，作为当前层的 top 偏移。要绘制第 i 层时，你必须知道：
        //         它的“上方”有多少层？上面那些层占了多少像素高度？绘制第1层从0开始，绘制第二层可能从55开始;
            sectionRect.setTop(rowSpanSize(logicalIdx, 0, i)); // distance from 0 to i-1 rows
        else
            sectionRect.setLeft(columnSpanSize(logicalIdx, 0, i));

        sectionRect.setSize(cellSize);

        // check up span column or row
        //返回该列所属合并区域的起始索引;
        QModelIndex colSpanIdx = columnSpanIndex(cellIndex);
        QModelIndex rowSpanIdx = rowSpanIndex(cellIndex);
        if (colSpanIdx.isValid()) {
            int colSpanFrom = colSpanIdx.column();
            int colSpanCnt = colSpanIdx.data(COLUMN_SPAN_ROLE).toInt();
            int colSpanTo = colSpanFrom + colSpanCnt - 1;
            int colSpan = columnSpanSize(cellIndex.row(), colSpanFrom, colSpanCnt);
            if (OTN == Qt::Horizontal)
                // sectionViewportPosition() 是 QHeaderView 的一个非常核心的布局函数，用于获取某一列（或某一行）在可视区域（viewport）中的起始坐标位置。返回给定逻辑索引（logicalIndex）的表头单元格在 viewport 坐标系下 的起始位置（以像素为单位）。也就是说：
        // 对水平表头（Qt::Horizontal）：返回列在X 方向上的起始像素位置；对垂直表头（Qt::Vertical）：返回行在Y 方向上的起始像素位置。//就是根据logicidnex第几列第几列,算出来该列在视图的位置
                sectionRect.setLeft(sectionViewportPosition(colSpanFrom));
            else {
                sectionRect.setLeft(columnSpanSize(logicalIdx, 0, colSpanFrom));
                i = colSpanTo;
            }

            sectionRect.setWidth(colSpan);

            // check up  if the column span index has row span
            //检查是否还有行合并;
            QVariant subRowSpanData = colSpanIdx.data(ROW_SPAN_ROLE);
            if (subRowSpanData.isValid()) {
                int subRowSpanFrom = colSpanIdx.row();
                int subRowSpanCnt = subRowSpanData.toInt();
                int subRowSpanTo = subRowSpanFrom + subRowSpanCnt - 1;
                int subRowSpan = rowSpanSize(colSpanFrom, subRowSpanFrom, subRowSpanCnt);
                if (OTN == Qt::Vertical)
                    sectionRect.setTop(sectionViewportPosition(subRowSpanFrom));
                else {
                    sectionRect.setTop(rowSpanSize(colSpanFrom, 0, subRowSpanFrom));

                    i = subRowSpanTo;
//                     跳过已合并的行防止重复绘制
                }
                sectionRect.setHeight(subRowSpan);
            }
            cellIndex = colSpanIdx;
        }
        if (rowSpanIdx.isValid()) {
            int rowSpanFrom = rowSpanIdx.row();
            int rowSpanCnt = rowSpanIdx.data(ROW_SPAN_ROLE).toInt();
            int rowSpanTo = rowSpanFrom + rowSpanCnt - 1;
            int rowSpan = rowSpanSize(cellIndex.column(), rowSpanFrom, rowSpanCnt);
            if (OTN == Qt::Vertical)
                sectionRect.setTop(sectionViewportPosition(rowSpanFrom));
            else {
                sectionRect.setTop(rowSpanSize(logicalIdx, 0, rowSpanFrom));
                i = rowSpanTo;
            }
            sectionRect.setHeight(rowSpan);

            // check up if the row span index has column span
            QVariant subColSpanData = rowSpanIdx.data(COLUMN_SPAN_ROLE);
            if (subColSpanData.isValid()) {
                int subColSpanFrom = rowSpanIdx.column();
                int subColSpanCnt = subColSpanData.toInt();
                int subColSpanTo = subColSpanFrom + subColSpanCnt - 1;
                int subColSpan = columnSpanSize(rowSpanFrom, subColSpanFrom, subColSpanCnt);
                if (OTN == Qt::Horizontal)
                    sectionRect.setLeft(sectionViewportPosition(subColSpanFrom));
                else {
                    sectionRect.setLeft(columnSpanSize(rowSpanFrom, 0, subColSpanFrom));
                    i = subColSpanTo;
                }
                sectionRect.setWidth(subColSpan);
            }
            cellIndex = rowSpanIdx;
        }

        // draw section with style
        QStyleOptionHeader sectionStyle;
        initStyleOption(&sectionStyle);
        sectionStyle.textAlignment = Qt::AlignCenter;
        sectionStyle.iconAlignment = Qt::AlignVCenter;
        sectionStyle.section = logicalIdx;
        sectionStyle.text = cellIndex.data(Qt::DisplayRole).toString();
        sectionStyle.rect = sectionRect;

        // file background or foreground color of the cell
        QVariant bg = cellIndex.data(Qt::BackgroundRole);
        QVariant fg = cellIndex.data(Qt::ForegroundRole);
        if (bg.canConvert(QVariant::Brush)) {
            sectionStyle.palette.setBrush(QPalette::Button, qvariant_cast<QBrush>(bg));
            sectionStyle.palette.setBrush(QPalette::Window, qvariant_cast<QBrush>(bg));
        }
        if (fg.canConvert(QVariant::Brush)) {
            sectionStyle.palette.setBrush(QPalette::ButtonText, qvariant_cast<QBrush>(fg));
        }

        painter->save();
        // 于绘制表头单元格的背景与边框，1:指定边框线条的宽度(像素)   最后:指向用于填充面板背景的画刷
        qDrawShadePanel(painter, sectionStyle.rect, sectionStyle.palette, false, 1,
                        &sectionStyle.palette.brush(QPalette::Button));
        style()->drawControl(QStyle::CE_HeaderLabel, &sectionStyle, painter);
        painter->restore();
    }
}

/*************************************************
 * 函数：sectionSizeFromContents
 * 功能：计算指定逻辑索引（logicalIndex）的表头单元格在内容层面的推荐尺寸。
 *       这个函数在 Qt 绘制表头时会被调用，用于确定每一列（或行）的理想宽度/高度。
 *
 * 参数：
 *   logicalIndex —— 当前要计算的逻辑列（或行）索引。
 *
 * 返回：
 *   QSize —— 表头的理想尺寸（宽度、高度）。
 *
 * 说明：
 *   该函数在默认 QHeaderView 行为的基础上，增加了对多层表头的支持。
 *   即如果单元格有跨列（column span）或跨行（row span），
 *   则根据实际合并范围重新计算尺寸。
 *************************************************/
// QSize RbTableHeaderView::sectionSizeFromContents(int logicalIndex) const {
//     // 将模型转换为自定义表头模型类型
//     const RbTableHeaderModel *tblModel = qobject_cast<const RbTableHeaderModel *>(this->model());
//
//     // 获取表头方向（水平 / 垂直）
//     const int OTN = orientation();
//
//     // 多层表头的层数（行数或列数）
//     const int LEVEL_CNT = (OTN == Qt::Horizontal)
//                               ? tblModel->rowCount()
//                               : tblModel->columnCount();
//
//     // 从父类获取基础尺寸（一般是根据字体或默认大小）
//     QSize siz = QHeaderView::sectionSizeFromContents(logicalIndex);
//
//     // 遍历多层表头的每一层
//     QSize resultSize = siz;
//     for (int i = 0; i < LEVEL_CNT; ++i) {
//
//         // 获取当前层级的单元格索引
//         QModelIndex cellIndex = (OTN == Qt::Horizontal)
//                                     ? tblModel->index(i, logicalIndex)   // 水平表头：第 i 行，第 logicalIndex 列
//                                     : tblModel->index(logicalIndex, i);  // 垂直表头：第 logicalIndex 行，第 i 列
//
//         // 检查当前单元格是否存在列合并或行合并
//         QModelIndex colSpanIdx = columnSpanIndex(cellIndex);
//         QModelIndex rowSpanIdx = rowSpanIndex(cellIndex);
//
//         // 从模型中读取单元格的建议大小（通常由 Qt::SizeHintRole 提供）
//         siz = cellIndex.data(Qt::SizeHintRole).toSize();
//
//         /***********************
//          * 处理列合并（Column Span）
//          ***********************/
//         if (colSpanIdx.isValid()) {
//             // 合并的起始列
//             int colSpanFrom = colSpanIdx.column();
//             // 跨越的列数
//             int colSpanCnt = colSpanIdx.data(COLUMN_SPAN_ROLE).toInt();
//             // 合并的结束列
//             int colSpanTo = colSpanFrom + colSpanCnt - 1;
//
//             // 计算合并后的总宽度
//             siz.setWidth(columnSpanSize(colSpanIdx.row(), colSpanFrom, colSpanCnt));
//
//             // 如果是垂直表头，则跳过被合并的列
//             if (OTN == Qt::Vertical)
//                 i = colSpanTo;
//         }
//
//         /***********************
//          * 处理行合并（Row Span）
//          ***********************/
//         if (rowSpanIdx.isValid()) {
//             // 合并的起始行
//             int rowSpanFrom = rowSpanIdx.row();
//             // 跨越的行数
//             int rowSpanCnt = rowSpanIdx.data(ROW_SPAN_ROLE).toInt();
//             // 合并的结束行
//             int rowSpanTo = rowSpanFrom + rowSpanCnt - 1;
//
//             // 计算合并后的总高度
//             siz.setHeight(rowSpanSize(rowSpanIdx.column(), rowSpanFrom, rowSpanCnt));
//
//             // 如果是水平表头，则跳过被合并的行
//             if (OTN == Qt::Horizontal)
//                 i = rowSpanTo;
//         }
//     }
//
//     //todo 此处重写,因为功能不够
//     // siz.setHeight(siz.height()+30);
//     // 返回计算出的推荐尺寸
//     return siz;
// }
QSize RbTableHeaderView::sectionSizeFromContents(int logicalIndex) const {
    const RbTableHeaderModel *tblModel = qobject_cast<const RbTableHeaderModel *>(this->model());
    const int OTN = orientation();
    const int LEVEL_CNT = (OTN == Qt::Horizontal) ? tblModel->rowCount() : tblModel->columnCount();

    QSize siz = QHeaderView::sectionSizeFromContents(logicalIndex);

    int totalWidth = siz.width();
    int totalHeight = 0;

    for (int i = 0; i < LEVEL_CNT; ++i) {
        QModelIndex cellIndex = (OTN == Qt::Horizontal)
                                ? tblModel->index(i, logicalIndex)
                                : tblModel->index(logicalIndex, i);

        QModelIndex colSpanIdx = columnSpanIndex(cellIndex);
        QModelIndex rowSpanIdx = rowSpanIndex(cellIndex);

        QSize cellSize = cellIndex.data(Qt::SizeHintRole).toSize();
        if (cellSize.isEmpty()) {
            cellSize = siz; // 使用默认尺寸
        }

        // 处理列合并
        if (colSpanIdx.isValid()) {
            int colSpanFrom = colSpanIdx.column();
            int colSpanCnt = colSpanIdx.data(COLUMN_SPAN_ROLE).toInt();
            int colSpanTo = colSpanFrom + colSpanCnt - 1;

            cellSize.setWidth(columnSpanSize(colSpanIdx.row(), colSpanFrom, colSpanCnt));

            if (OTN == Qt::Vertical)
                i = colSpanTo;
        }

        // 处理行合并
        if (rowSpanIdx.isValid()) {
            int rowSpanFrom = rowSpanIdx.row();
            int rowSpanCnt = rowSpanIdx.data(ROW_SPAN_ROLE).toInt();
            int rowSpanTo = rowSpanFrom + rowSpanCnt - 1;

            cellSize.setHeight(rowSpanSize(rowSpanIdx.column(), rowSpanFrom, rowSpanCnt));

            if (OTN == Qt::Horizontal) {
                // 累加合并后的高度
                totalHeight += cellSize.height();
                i = rowSpanTo; // 跳过被合并的行
            }
        } else {
            // 没有行合并，直接累加当前行高度
            totalHeight += cellSize.height();
        }

        // 更新最大宽度
        if (cellSize.width() > totalWidth) {
            totalWidth = cellSize.width();
        }
    }

    // 确保高度至少是所有行的累加
    if (totalHeight == 0) {
        // 如果没有计算高度，使用默认逻辑
        totalHeight = siz.height();
    }

    return QSize(totalWidth, totalHeight);
}

// 查找包含当前单元格的跨列单元格的起始索引。找到返回,找不到,返回为空,帮助确定当前列所属的合并区域。
QModelIndex RbTableHeaderView::columnSpanIndex(const QModelIndex &currentIdx) const {
    const RbTableHeaderModel *tblModel = qobject_cast<RbTableHeaderModel *>(model());
    const int curRow = currentIdx.row();
    const int curCol = currentIdx.column();
    int i = curCol;
    while (i >= 0) {
        QModelIndex spanIndex = tblModel->index(curRow, i);
        QVariant span = spanIndex.data(COLUMN_SPAN_ROLE);
        // 用于检查当前列是否在一个跨列范围内,是的话,返回该列的起始索引
        if (span.isValid() && spanIndex.column() + span.toInt() - 1 >= curCol)
            return spanIndex;
        i--;
    }
    return QModelIndex();
}

QModelIndex RbTableHeaderView::rowSpanIndex(const QModelIndex &currentIdx) const {
    const RbTableHeaderModel *tblModel = qobject_cast<RbTableHeaderModel *>(model());
    const int curRow = currentIdx.row();
    const int curCol = currentIdx.column();
    int i = curRow;
    while (i >= 0) {
        QModelIndex spanIndex = tblModel->index(i, curCol);
        QVariant span = spanIndex.data(ROW_SPAN_ROLE);
        if (span.isValid() && spanIndex.row() + span.toInt() - 1 >= curRow)
            return spanIndex;
        i--;
    }
    return QModelIndex();
}

int RbTableHeaderView::columnSpanSize(int row, int from, int spanCount) const {
    const RbTableHeaderModel *tblModel = qobject_cast<RbTableHeaderModel *>(model());
    int span = 0;
    for (int i = from; i < from + spanCount; ++i) {
        QSize cellSize = tblModel->index(row, i).data(Qt::SizeHintRole).toSize();
        span += cellSize.width();
    }
    return span;
}


int RbTableHeaderView::rowSpanSize(int column, int from, int spanCount) const {
    // 因为只有该模型才提供多层表头、单元格尺寸（SizeHintRole）等信息。
    const RbTableHeaderModel *tblModel = qobject_cast<RbTableHeaderModel *>(model());

    // 用于累加高度的变量
    int span = 0;

    // 遍历从 "from" 开始的连续 spanCount 行（即垂直方向上合并的范围）
    // 例如：from = 0, spanCount = 3 -> 表示行 0、1、2。
    for (int i = from; i < from + spanCount; ++i) {
        // 取得 (i, column) 单元格对应的模型索引
        // 并从模型中读取该单元格的 SizeHintRole（建议尺寸）。
        QSize cellSize = tblModel->index(i, column).data(Qt::SizeHintRole).toSize();

        // 将每个单元格的高度累加，得到合并后单元格的总高度。
        span += cellSize.height();
    }

    // 返回累加的高度总和，即该列从指定起点行开始、跨越 spanCount 行的总像素高度。
    return span;
}

/**
 * @return section numbers
 */
int RbTableHeaderView::getSectionRange(QModelIndex &index, int *beginSection, int *endSection) const {
    // check up section range from the index
    QModelIndex colSpanIdx = columnSpanIndex(index);
    QModelIndex rowSpanIdx = rowSpanIndex(index);

    if (colSpanIdx.isValid()) {
        int colSpanFrom = colSpanIdx.column();
        int colSpanCnt = colSpanIdx.data(COLUMN_SPAN_ROLE).toInt();
        int colSpanTo = colSpanFrom + colSpanCnt - 1;
        if (orientation() == Qt::Horizontal) {
            *beginSection = colSpanFrom;
            *endSection = colSpanTo;
            index = colSpanIdx;
            return colSpanCnt;
        } else {
            // check up  if the column span index has row span
            QVariant subRowSpanData = colSpanIdx.data(ROW_SPAN_ROLE);
            if (subRowSpanData.isValid()) {
                int subRowSpanFrom = colSpanIdx.row();
                int subRowSpanCnt = subRowSpanData.toInt();
                int subRowSpanTo = subRowSpanFrom + subRowSpanCnt - 1;
                *beginSection = subRowSpanFrom;
                *endSection = subRowSpanTo;
                index = colSpanIdx;
                return subRowSpanCnt;
            }
        }
    }

    if (rowSpanIdx.isValid()) {
        int rowSpanFrom = rowSpanIdx.row();
        int rowSpanCnt = rowSpanIdx.data(ROW_SPAN_ROLE).toInt();
        int rowSpanTo = rowSpanFrom + rowSpanCnt - 1;
        if (orientation() == Qt::Vertical) {
            *beginSection = rowSpanFrom;
            *endSection = rowSpanTo;
            index = rowSpanIdx;
            return rowSpanCnt;
        } else {
            // check up if the row span index has column span
            QVariant subColSpanData = rowSpanIdx.data(COLUMN_SPAN_ROLE);
            if (subColSpanData.isValid()) {
                int subColSpanFrom = rowSpanIdx.column();
                int subColSpanCnt = subColSpanData.toInt();
                int subColSpanTo = subColSpanFrom + subColSpanCnt - 1;
                *beginSection = subColSpanFrom;
                *endSection = subColSpanTo;
                index = rowSpanIdx;
                return subColSpanCnt;
            }
        }
    }

    return 0;
}


void RbTableHeaderView::onSectionResized(int logicalIndex, int oldSize, int newSize) {
    Q_UNUSED(oldSize);
    RbTableHeaderModel *tblModel = qobject_cast<RbTableHeaderModel *>(this->model());
    const int OTN = orientation();
    const int LEVEL_CNT = (OTN == Qt::Horizontal) ? tblModel->rowCount() : tblModel->columnCount();
    int pos = sectionViewportPosition(logicalIndex);
    int xx = (OTN == Qt::Horizontal) ? pos : 0;
    int yy = (OTN == Qt::Horizontal) ? 0 : pos;
    QRect sectionRect(xx, yy, 0, 0);
    for (int i = 0; i < LEVEL_CNT; ++i) {
        QModelIndex cellIndex = (OTN == Qt::Horizontal)
                                    ? tblModel->index(i, logicalIndex)
                                    : tblModel->index(logicalIndex, i);
        QSize cellSize = cellIndex.data(Qt::SizeHintRole).toSize();
        // set position of cell
        if (OTN == Qt::Horizontal) {
            sectionRect.setTop(rowSpanSize(logicalIndex, 0, i));
            cellSize.setWidth(newSize);
        } else {
            sectionRect.setLeft(columnSpanSize(logicalIndex, 0, i));
            cellSize.setHeight(newSize);
        }
        tblModel->setData(cellIndex, cellSize, Qt::SizeHintRole);

        QModelIndex colSpanIdx = columnSpanIndex(cellIndex);
        QModelIndex rowSpanIdx = rowSpanIndex(cellIndex);

        if (colSpanIdx.isValid()) {
            int colSpanFrom = colSpanIdx.column();
            if (OTN == Qt::Horizontal)
                sectionRect.setLeft(sectionViewportPosition(colSpanFrom));
            else {
                sectionRect.setLeft(columnSpanSize(logicalIndex, 0, colSpanFrom));
            }
        }
        if (rowSpanIdx.isValid()) {
            int rowSpanFrom = rowSpanIdx.row();
            if (OTN == Qt::Vertical)
                sectionRect.setTop(sectionViewportPosition(rowSpanFrom));
            else
                sectionRect.setTop(rowSpanSize(logicalIndex, 0, rowSpanFrom));
        }
        QRect rToUpdate(sectionRect);
        rToUpdate.setWidth(viewport()->width() - sectionRect.left());
        rToUpdate.setHeight(viewport()->height() - sectionRect.top());
        viewport()->update(rToUpdate.normalized());
    }
}
